#ifndef __H__MVP_NODE_H__
#define __H__MVP_NODE_H__

#include <memory>
#include <string>

#include "node/reader.h"
#include "node/writer.h"

namespace motovis
{

class Node
{
  public:
    friend std::unique_ptr<Node> createNode(const std::string &node_name,
                                            const std::string &name_space);

    virtual ~Node();

    const std::string &name() const;

    using TraModPtr = transport::TransportModel;
    template <typename MessageT>
    auto createWriter(const std::string &channel_nam,
                      const TraModPtr &model = TraModPtr::SHM)
        -> std::shared_ptr<Writer<MessageT>>;

    template <typename MessageT>
    auto createReader(const std::string &channel_name,
                      const CallbackFunc<MessageT> &,
                      const TraModPtr &model = TraModPtr::SHM)
        -> std::shared_ptr<Reader<MessageT>>;

  private:
    explicit Node(const std::string &node_name,
                  const std::string &name_space = "");

    std::string node_name_;
    std::string name_space_;
};

template <typename MessageT>
auto Node::createWriter(const std::string &channel_name,
                        const TraModPtr &model)
    -> std::shared_ptr<Writer<MessageT>>
{
    return std::make_shared<Writer<MessageT>>(channel_name, model);
}

template <typename MessageT>
auto Node::createReader(const std::string &channel_name,
                        const CallbackFunc<MessageT> &reader_func,
                        const TraModPtr &model)
    -> std::shared_ptr<Reader<MessageT>>
{
    return std::make_shared<Reader<MessageT>>(channel_name, reader_func, model);
}

} // namespace motovis

#endif //__H__MVP_NODE_H__
